import os
import re
from pathlib import Path
from collections.abc import Iterable

import pytest
from pytest import CaptureFixture

from gemini_antenna.URLHelper import URLHelper
from gemini_antenna.db import AntennaDB
from gemini_antenna.cgi import customFilters


def pytest_configure():
    pytest.filter_script_name = "/~antenna/cgi-bin/filter"
    pytest.filter_redirect = re.compile(
        rf"30 {pytest.filter_script_name}/([a-zA-Z]{{32}})\r\n"
    )


def write_blocklist(directory: Path, rules: Iterable[str]) -> str:
    """
    Write blocklist.txt file.

    :param directory: Parent directory for the blocklist.txt file.
    :param rules: URL prefixes to block.
    :returns: Path to the blocklist.txt file.
    """
    blocklist = directory / "blocklist.txt"
    with open(blocklist, "w") as blockfile:
        blockfile.write("\n".join(rules))
    return blocklist


@pytest.fixture
def url_helper(request: pytest.FixtureRequest, tmp_path: Path) -> URLHelper:
    marker = request.node.get_closest_marker("blocklist_rules")
    if marker is None:
        return URLHelper

    blocklist = write_blocklist(tmp_path, marker.args)
    return URLHelper(blocklist)


@pytest.fixture
def db(request: pytest.FixtureRequest, tmp_path: Path) -> AntennaDB:
    os.environ['ANTENNA_DATAROOT'] = str(tmp_path)

    marker = request.node.get_closest_marker("blocklist_rules")
    if marker is not None:
        write_blocklist(tmp_path, marker.args)

    antennaDB = AntennaDB(tmp_path / "antenna.sqlite")
    antennaDB.createDB()

    return antennaDB


@pytest.fixture
def filter_name(db: AntennaDB, capfd: CaptureFixture[str]) -> str:
    """
    Create a new filter.

    :returns: Filter's name (32 random characters).
    """
    os.environ['SCRIPT_NAME'] = pytest.filter_script_name
    os.environ['QUERY_STRING'] = "y"

    customFilters.main()
    out = capfd.readouterr().out

    return pytest.filter_redirect.match(out).group(1)
